package com.aispeech.aicube.robot;

import android.media.AudioManager;
import android.text.TextUtils;
import android.util.Log;

import com.aispeech.aicube.voice.observer.DuiCommandObserver;
import com.aispeech.aicube.voice.observer.DuiNativeApiObserver;
import com.aispeech.aicube.voice.observer.DuiUpdateObserver;
import com.aispeech.dui.dds.DDS;
import com.aispeech.dui.dds.agent.wakeup.word.WakeupWord;
import com.aispeech.dui.dds.exceptions.DDSNotInitCompleteException;
import com.aispeech.player.BaseNode;
import com.aispeech.player.BusClient;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;

public class MyVoice extends BaseNode implements DuiUpdateObserver.UpdateCallback {//, DuiMessageObserver.MessageCallback {
    private final String TAG = "MyVoice";

    private VoiceListener mListener;

//    private LinkedList<MessageBean> mMessageList;

    //    private DuiMessageObserver mMessageObserver = new DuiMessageObserver();// 消息监听器
    private DuiUpdateObserver mUpdateObserver = new DuiUpdateObserver();// dds更新监听器
    private DuiCommandObserver mCommandObserver = new DuiCommandObserver();// 命令监听器
    private DuiNativeApiObserver mNativeApiObserver = new DuiNativeApiObserver();// 本地方法回调监听器

    public static final String[] CUBE_WK_CMD_START = {"wo yao zhuang bi", "我要装逼", "0.12", "复原看心情，装逼需谨慎", "cube.start_performance"};
    public static final String[] CUBE_WK_CMD_START2 = {"rang wo kan yi xia", "让我看下", "0.12", "你去热个身，让我来看吧", "cube.start_performance"};
    public static final String[] CUBE_WK_CMD_REVISE = {"rang wo xiang xiang", "让我想想", "0.12", "返回三步", "cube.revise"};
    public static final String[] CUBE_WK_CMD_WAIT = {"deng yi xia", "等一下", "0.14", "返回三步", "cube.revise"};

    public MyVoice() {
    }

    @Override
    public BusClient.RPCResult onCall(String s, byte[]... bytes) throws Exception {
        return null;
    }

    @Override
    public void onJoin() {
        super.onJoin();
        Log.d(TAG, "onJoin: ");
        bc.subscribe("local_recorder.pcm");
//        bc.subscribe("sys.dialog.start");
//        bc.subscribe("sys.dialog.end");
//        bc.subscribe("local_recorder.state");
//        bc.subscribe("local_vad.state");
//        bc.subscribe("local_asr.state");
//
//        bc.subscribe("local_vad.pcm");
//        bc.subscribe("local_aec.pcm");
//        bc.subscribe("local_asr.pcm");
//
//        bc.subscribe("asr.speech.text");
//        bc.subscribe("asr.speech.result");
//        bc.subscribe("context.output.text");
//        bc.subscribe("dm.output");
//
//        bc.subscribe("local_wakeup.state");
//
//        bc.subscribe("ui.avatar.click");// 近场

    }

    @Override
    public void onMessage(String topic, byte[]... parts) throws Exception {
        super.onMessage(topic, parts);
//        Log.d(TAG, "onMessage: " + topic);

        if (topic.equals("local_recorder.pcm") && null != parts && parts.length > 1) {
            MyMemory.getInstance().recordAudio(parts[1], parts[1].length);
        }
    }

    @Override
    public String getName() {
        return "debug_audio";
    }

    public void open(VoiceListener listener) {
        mListener = listener;
        int initStatus = DDS.getInstance().getInitStatus();
        if (initStatus == DDS.INIT_COMPLETE_FULL) {
            Log.d(TAG, "checkDDSInitComplete: INIT_COMPLETE_FULL");
            enableWakeup();

            Log.d(TAG, "wait for wakeup...");
            setCubeCMDWakeupWords();
            setTTSType();

            mUpdateObserver.regist(this);
            mCommandObserver.regist(listener);
            mNativeApiObserver.regist();

//            mMessageList = new LinkedList<>();
//            mMessageObserver.regist(this, mMessageList);
            this.start();

            MyMemory.getInstance().initAudioCodec();

            mListener.onVoiceOpen();
        } else {
            Log.e(TAG, "open: you must call this after init complete full ");
            mListener.onVoiceClose();
        }
//        else {
//            Log.e(TAG, "open: dds not init complete");
//            // 添加一个初始成功的广播监听器
//            IntentFilter filter = new IntentFilter();
//            filter.addAction("ddsdemo.intent.action.init_complete");
//        }
    }

    private void setTTSType() {
        try {
            Log.d(TAG, "setTTSType: set tts to music, cause we need play tts only on ble earphone");
            DDS.getInstance().getAgent().getTTSEngine().setStreamType(AudioManager.STREAM_MUSIC);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void close() {
        Log.d(TAG, "close: ");
        this.stop();

        disableWakeup();

        if (null != mListener) {
            mListener.onVoiceClose();
        }

        mUpdateObserver.unregist();
        mCommandObserver.unregist();
        mNativeApiObserver.unregist();
    }

    public void speak(String context) {
        Log.d(TAG, "speak() called with: context = [" + context + "]");
        if (TextUtils.isEmpty(context)) {
            return;
        }
        try {
            if (DDS.getInstance().getAgent() == null) {
                Log.e(TAG, "onStart agent is null, return ...");
                return;
            }
            UUID ttsUuid = UUID.randomUUID();
            String tus = ttsUuid.toString();
            Log.d(TAG, "speak: ttsUuid = " + tus);
            DDS.getInstance().getAgent().getTTSEngine().speak(context, 3, tus, AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK);
        } catch (DDSNotInitCompleteException e) {
            e.printStackTrace();
        }
    }

    // 打开唤醒，调用后才能语音唤醒
    void enableWakeup() {
        try {
            DDS.getInstance().getAgent().getWakeupEngine().enableWakeup();
        } catch (DDSNotInitCompleteException e) {
            e.printStackTrace();
        }
    }

    // 关闭唤醒, 调用后将无法语音唤醒
    void disableWakeup() {
        try {
            DDS.getInstance().getAgent().stopDialog();
            DDS.getInstance().getAgent().getWakeupEngine().disableWakeup();
        } catch (DDSNotInitCompleteException e) {
            e.printStackTrace();
        }
    }


    // dds初始化成功之后,展示一个打招呼消息,告诉用户可以开始使用
    public void setCubeCMDWakeupWords() {
        String[] wakeupWords;
        String minorWakeupWord;

        try {
            // 获取主唤醒词
            wakeupWords = DDS.getInstance().getAgent().getWakeupEngine().getWakeupWords();

            Log.d(TAG, "wakeupWords: " + Arrays.toString(wakeupWords));

            // 实时更新命令唤醒词-更新多条命令唤醒词(1.1.2.1版本及以上支持)
            WakeupWord commandWord1 = new WakeupWord()
                    .setPinyin(CUBE_WK_CMD_START[0])
                    .setWord(CUBE_WK_CMD_START[1])
                    .setThreshold(CUBE_WK_CMD_START[2])
                    .addGreeting(CUBE_WK_CMD_START[3])
                    .setAction(CUBE_WK_CMD_START[4]);

            WakeupWord commandWord2 = new WakeupWord()
                    .setPinyin(CUBE_WK_CMD_START2[0])
                    .setWord(CUBE_WK_CMD_START2[1])
                    .setThreshold(CUBE_WK_CMD_START2[2])
                    .addGreeting(CUBE_WK_CMD_START2[3])
                    .setAction(CUBE_WK_CMD_START2[4]);

            WakeupWord commandWord3 = new WakeupWord()
                    .setPinyin(CUBE_WK_CMD_REVISE[0])
                    .setWord(CUBE_WK_CMD_REVISE[1])
                    .setThreshold(CUBE_WK_CMD_REVISE[2])
                    .addGreeting(CUBE_WK_CMD_REVISE[3])
                    .setAction(CUBE_WK_CMD_REVISE[4]);

            WakeupWord commandWord4 = new WakeupWord()
                    .setPinyin(CUBE_WK_CMD_WAIT[0])
                    .setWord(CUBE_WK_CMD_WAIT[1])
                    .setThreshold(CUBE_WK_CMD_WAIT[2])
                    .addGreeting(CUBE_WK_CMD_WAIT[3])
                    .setAction(CUBE_WK_CMD_WAIT[4]);


            List<WakeupWord> commandList = new ArrayList<>();
            commandList.add(commandWord1);
            commandList.add(commandWord2);
            commandList.add(commandWord3);
            commandList.add(commandWord4);

            DDS.getInstance().getAgent().getWakeupEngine().updateCommandWakeupWords(commandList);

            // 获取副唤醒词
            minorWakeupWord = DDS.getInstance().getAgent().getWakeupEngine().getMinorWakeupWord();
            Log.d(TAG, "minorWakeupWord: " + minorWakeupWord);
        } catch (DDSNotInitCompleteException e) {
            e.printStackTrace();
        }
    }

//    @Override
//    public void onMessage() {
//        Log.d(TAG, "onMessage() called");
//    }
//
//    @Override
//    public void onState(String state) {
//        Log.d(TAG, "onState() called with: state = [" + state + "]");
//        switch (state) {
//            case "avatar.silence":
//                Log.d(TAG, "等待唤醒...");
//                break;
//            case "avatar.listening":
//                Log.d(TAG, "监听中...");
//                break;
//            case "avatar.understanding":
//                Log.d(TAG, "理解中...");
//                break;
//            case "avatar.speaking":
//                Log.d(TAG, "播放语音中...");
//                break;
//        }
//    }

    @Override
    public void onUpdate(int type, String result) {
        Log.d(TAG, "onUpdate() called with: type = [" + type + "], result = [" + result + "]");
    }

    public interface VoiceListener {
        void onVoiceOpen();

        void onVoiceClose();

        void onVoiceCMD(MyBrain.BRAIN_EVENT event);
    }
}